home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / prolog / emacs19 / swi_prol.el < prev    next >
Encoding:
Text File  |  1993-12-02  |  8.6 KB  |  302 lines

  1. ;;; Interface to SWI-Prolog
  2. ;;; Author: Jan Wielemaker, SWI, University of Amsterdam
  3. ;;; E-mail: jan@swi.psy.uva.nl
  4.  
  5. ;;; This package forms a layer around the Quintus-Prolog interface.  It
  6. ;;; should be used together with the Prolog library 'emacs_interface.pl'.
  7.  
  8. ;;; It implements hooks that allow SWI-Prolog to give compilation-warnings
  9. ;;; back to EMACS, so the user can step through them using the normal
  10. ;;; ^X` command
  11.  
  12. ;;; Usage:
  13. ;;;
  14. ;;;     Put the following lines in your ~/.emacs:
  15. ;;;
  16. ;;;    (autoload 'run-prolog "swi-prolog" "Run an inferior prolog process" t)
  17. ;;;    (autoload 'prolog-mode "swi-prolog" "SWI-Prolog mode" t)
  18.  
  19. ;;; Notes:
  20. ;;;
  21. ;;; As far as I was able to figure out, the Quintus Prolog GNU-Emacs lisp
  22. ;;; interface can be distributed under the normal GNU general public licence
  23. ;;;
  24. ;;; This file is distributed confirm the GNU general public licence.
  25.  
  26.  
  27. (defconst qplisp-directory "/usr/local/Emacs19/lib/emacs/site-lisp/qplisp"
  28.   "Directory with all the quintus interface files")
  29. (defvar run-prolog-command "pl"
  30.   "Command to start SWI-Prolog")
  31. (defconst prolog-warning-buffer "*compilation*"
  32.   "SWI-Prolog buffer for warnings")
  33.  
  34. ;;; Get the Quintus EMACS library in your load path
  35.  
  36. (setq load-path (cons qplisp-directory load-path))
  37. (load-library "qprolog-mode")
  38.  
  39. ;;; "compile.el" that comes with Emacs19 does not seem to work very well.
  40. ;;; Especially, error messages are not parsed correctly. It might be the
  41. ;;; case that errors are treated somewhat differently in Emacs19. Jan?
  42. ;;;
  43. (load-library "compile18")
  44.  
  45. (setq prolog-prompt-pattern "^[0-9]+ \\?- ")
  46.  
  47.  
  48. ;;; Prolog Mode popup windows (Manfred Aben)
  49. ;;;
  50.  
  51. (require 'easymenu)
  52.  
  53. (defvar prolog-menu nil
  54.   "Popup menu with the available commands for SWI-prolog mode")
  55.  
  56. (setq prolog-menu
  57.       '("Prolog"
  58.     ["Start SWI-Prolog"         run-prolog             t]
  59.     ["Interrupt Prolog"         interrupt-prolog         t]
  60.     " "
  61.     ["Consult this file"                 prolog-compile-buffer-only    t]
  62.     ["Reconsult modified files"        prolog-recompile             t]
  63.     "  "
  64.     ["Go to next error"                next-error             t]
  65.     "   "
  66.     ["Previous query"        prolog-previous-command     t]
  67.     ["Next query"             prolog-next-command         t]
  68.     "    "
  69.     ["Find source file of this term" find-definition               t]
  70.     ["Find other source files"         find-more-definition         t]
  71.     "     "
  72.     ["Select clause"         mark-clause                 t]
  73.     ["Delete clause"         kill-clause             t]
  74.     ["Indent clause"         prolog-indent-clause         t]
  75.     ))
  76.  
  77.  
  78. (or (fboundp 'old-prolog-mode)
  79.     (fset 'old-prolog-mode
  80.       (symbol-function 'prolog-mode)))
  81.  
  82. (defun prolog-mode ()
  83.   "Major mode for editing files of prolog code.
  84.  The following commands are available:
  85. \\{prolog-mode-map}."
  86.   (interactive)
  87.   ;;; HACK; Q-prolog-mode complains about "mark not active"
  88.   (set-mark (beginning-of-buffer))
  89.   (old-prolog-mode)
  90.   (easy-menu-define menu-bar-swi-prolog1-commands
  91.       prolog-mode-map
  92.       "SWI-Prolog mode commands"
  93.     prolog-menu))
  94.  
  95. (defun prolog-compilation-start (dir)
  96.   "Clear *compilation* buffer"
  97.   (save-excursion
  98.     (set-buffer (get-buffer-create prolog-warning-buffer))
  99.     (erase-buffer)
  100.     (setq default-directory dir)
  101.     (compilation-forget-errors)
  102.     (setq compilation-error-list t)
  103.     (setq compilation-error-message "No more SWI-Prolog errors")
  104.     (insert "cd " dir)
  105.     (newline)
  106.     (insert "SWI-Prolog warnings")
  107.     (newline)))
  108.  
  109.  
  110. (defun prolog-compilation-finish ()
  111.   "Finish prolog-compilation"
  112.   (save-excursion
  113.     (set-buffer prolog-warning-buffer)
  114.     (end-of-buffer)
  115.     (newline 2)
  116.     (insert "Compilation finished at " (current-time-string))
  117.     (newline)
  118.     (setq compilation-parsing-end 1)))
  119.  
  120.  
  121. (defun prolog-compilation-warning (file line msg)
  122.   "Put a prolog error-message in *compilation*"
  123.   (save-excursion
  124.     (set-buffer prolog-warning-buffer)
  125.     (end-of-buffer)
  126.     (display-buffer (current-buffer))
  127.     (insert file ":" line ": " msg)
  128.     (newline)))
  129.  
  130.  
  131. ;;; STARTING PROLOG
  132. ;;; This function is a modified version of run-prolog in qprolog-mode.el
  133.  
  134. (defun run-prolog (command)
  135.   "Run an inferior SWI-Prolog process, input and output via buffer
  136. *prolog*."
  137.   (interactive (list (read-string "Run prolog: " run-prolog-command)))
  138.   (setq run-prolog-command command)
  139.   (ensure-prolog-syntax)
  140.   (qprequire 'shell)
  141.   (get-prolog-exec-and-flags (concat command startup-jcl))
  142.   (switch-to-buffer-other-window (apply 'make-comint "prolog"
  143.                     *prolog-executable* nil  
  144.                     *prolog-flags*))
  145.   (set-process-filter (get-process "prolog") 'prolog-process-filter)
  146.   (sleep-for 2)
  147.   (inferior-prolog-mode)
  148.   (local-set-key "\t" 'prolog-dabbrev-atom)
  149.   (local-set-key "\C-d" 'prolog-complete-atom)
  150.   (local-set-key "\C-c\C-n" 'prolog-next-command)
  151.   (local-set-key "\C-c\C-p" 'prolog-previous-command)
  152.   
  153.   (easy-menu-define menu-bar-swi-prolog2-commands
  154.       inferior-prolog-mode-map
  155.       "SWI-Prolog mode commands"
  156.     prolog-menu))
  157.  
  158. ;;; ATOM COMPLETION
  159.  
  160. (defvar *prolog-start-completion* nil
  161.   "Start of prolog completion")
  162. (defvar *prolog-end-completion* nil
  163.   "End of prolog completion")
  164. (defvar *prolog-atom-completions* nil
  165.   "Collect-list for prolog completions")
  166. (defvar *prolog-completion-process-mark* nil
  167.   "Process mark when starting completion")
  168.  
  169. (defun prolog-completion-backward-word ()
  170.   (interactive)
  171.   (backward-word 1)
  172.   (backward-char 1)
  173.   (if (looking-at "_")
  174.       (prolog-completion-backward-word)
  175.       (forward-char 1)))
  176.  
  177.  
  178. (defun prolog-completion-sofar ()
  179.   (setq *prolog-end-completion* (point))
  180.   (let ((end (point)))
  181.     (save-excursion
  182.       (backward-char 1)
  183.       (cond ((looking-at "[a-zA-Z0-9_]\\b")
  184.          (prolog-completion-backward-word)
  185.          (setq *prolog-start-completion* (point))
  186.          (setq *prolog-completion-process-mark*
  187.            (marker-position (process-mark
  188.                      (get-buffer-process "*prolog*"))))
  189.          (buffer-substring (point) end))
  190.         (t nil)))))
  191.  
  192. (defun prolog-complete-atom-with (extended unique)
  193.   (cond ((eq *prolog-end-completion* (point))
  194.      (kill-region *prolog-start-completion* *prolog-end-completion*)
  195.      (insert extended)
  196.      (setq *saved-prolog-process-mark* *prolog-completion-process-mark*)
  197.      (if (not unique) (message "[incomplete]")))
  198.     (t
  199.      (prolog-completion-error-message "Mismatch of dabbrev-point"))))
  200.  
  201. (defun prolog-completion-error-message (string)
  202.   (message string)
  203.   (setq *saved-prolog-process-mark* *prolog-completion-process-mark*))
  204.  
  205. ;;; DABBREV
  206.  
  207. (defun prolog-dabbrev-atom ()
  208.   (interactive)
  209.   (let (sofar)
  210.     (cond ((setq sofar (prolog-completion-sofar))
  211.        (send-prolog (concat 
  212.              "'$silent'(emacs_dabbrev_atom(\""
  213.              sofar
  214.              "\"))")))
  215.       (t
  216.        (message "Point not at end of atom")))))
  217.  
  218. ;;; COMPLETION
  219.  
  220. (defun prolog-complete-atom ()
  221.   (interactive)
  222.   (let (sofar)
  223.     (cond ((setq sofar (prolog-completion-sofar))
  224.        (send-prolog (concat
  225.              "'$silent'(emacs_complete_atom(\""
  226.              sofar
  227.              "\"))")))
  228.       (t
  229.        (message "Point not at end of atom")))))
  230.         
  231. (defun prolog-completions-start-collect ()
  232.   (setq *prolog-atom-completions* nil))
  233.  
  234. (defun prolog-transfer-completion (atom number)
  235.   (setq *prolog-atom-completions*
  236.     (cons (list atom number)
  237.           *prolog-atom-completions*)))
  238.  
  239. (defun prolog-completions-run (sofar)
  240.   (prolog-complete-atom-with
  241.    (completing-read "Complete atom: "
  242.             *prolog-atom-completions*
  243.             nil
  244.             nil
  245.             sofar)
  246.    t))
  247.   
  248. ;;; HISTORY
  249.  
  250. (defun prolog-previous-command ()
  251.   (interactive)
  252.   (end-of-buffer)
  253.   (setq *prolog-completion-process-mark*
  254.     (marker-position (process-mark (get-buffer-process "*prolog*"))))
  255.   (send-prolog "'$silent'(emacs_previous_command)"))
  256.  
  257.  
  258. (defun prolog-next-command ()
  259.   (interactive)
  260.   (end-of-buffer)
  261.   (setq *prolog-completion-process-mark*
  262.     (marker-position (process-mark (get-buffer-process "*prolog*"))))
  263.   (send-prolog "'$silent'(emacs_next_command)"))
  264.  
  265.  
  266. (defun prolog-insert-history-command (cmd)
  267.   (kill-region *prolog-completion-process-mark* (point))
  268.   (insert cmd ".")
  269.   (setq *saved-prolog-process-mark* *prolog-completion-process-mark*))
  270.  
  271.  
  272. ;;; COMPILATION
  273.  
  274. (defun prolog-recompile ()
  275.   (interactive)
  276.   (save-some-buffers)
  277.   (if (not (eq (current-buffer) (get-buffer "*prolog*")))
  278.       (pop-to-buffer (get-buffer "*prolog*") nil))
  279.   (end-of-buffer)
  280.   (insert "make.\n")
  281.   (send-prolog "make"))
  282.  
  283. (defun prolog-compile-buffer-only ()
  284.   "to avoid complications with compile-region and compile-predicate"
  285.   (interactive)
  286.   (let* ((file-name (buffer-file-name))
  287.      (command (concat "['" file-name "']")))
  288.     (if (eq (current-buffer) (get-buffer "*prolog*"))
  289.     (error "Cannot compile *prolog* buffer!")
  290.       (save-some-buffers)
  291.       (pop-to-buffer (get-buffer "*prolog*") nil)
  292.       (end-of-buffer)
  293.       (insert command)
  294.       (insert ".\n")
  295.       (send-prolog command))))
  296.  
  297. ;;; Show SWI prolog help info in separate window
  298. (defun prolog-help (filename from to)
  299.   (find-file-other-window filename)
  300.   (widen)
  301.   (narrow-to-region from to))
  302.